﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.BackgroundTransfer;
using System.IO.IsolatedStorage;
using MangaForYou.Class;
using DBDataContext.Model;
using Microsoft.Phone.Net.NetworkInformation;

namespace WolfGuy
{
    public partial class DownloadPage : PhoneApplicationPage
    {
        //IEnumerable<BackgroundTransferRequest> transferRequests;
        // Booleans for tracking if any transfers are waiting for user action.
        bool WaitingForExternalPower;
        bool WaitingForExternalPowerDueToBatterySaverMode;
        bool WaitingForNonVoiceBlockingNetwork;
        bool WaitingForWiFi;
        Manga manga;
        List<int> lstMangaId;
        public DownloadPage()
        {
            InitializeComponent();
        }

        private void UpdateRequestsList()
        {
            // The Requests property returns new references, so make sure that
            // you dispose of the old refereneces to avoid memory leaks.
            if (BackgroundTransferService.Requests != null)
            {
                foreach (var request in BackgroundTransferService.Requests)
                {
                    request.Dispose();
                }
            }

            // the Requests property returns a list of new BackgroundTransferRequest objects
            //BackgroundTransferService.Requests = BackgroundTransferService.Requests;
        }

        private void UpdateUI()
        {
            // Update the list of transfer requests
            UpdateRequestsList();

            // If there are 1 or more transfers, hide the "no transfers"
            // TextBlock. IF there are zero transfers, show the TextBlock.
            if (BackgroundTransferService.Requests.Count() > 0)
            {
                EmptyTextBlock.Visibility = Visibility.Collapsed;
            }
            else
            {
                EmptyTextBlock.Visibility = Visibility.Visible;
            }

            // Update the TransferListBox with the list of transfer requests.
            TransferListBox.ItemsSource = BackgroundTransferService.Requests;

        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            // Reset all of the user action booleans on page load.
            WaitingForExternalPower = false;
            WaitingForExternalPowerDueToBatterySaverMode = false;
            WaitingForNonVoiceBlockingNetwork = false;
            WaitingForWiFi = false;

            // When the page loads, refresh the list of file transfers.
            if ((App.Current as App).isAutoDownload == false)
            {
                InitialTransferStatusCheck();
            }
            else
            {
                UpdateRequestsList();

                foreach (var transfer in BackgroundTransferService.Requests)
                {
                    //transfer.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferStatusChanged);
                    transfer.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferProgressChanged);
                    ProcessTransfer(transfer);
                }
            }

            this.btnAction.IsEnabled = !(App.Current as App).isAutoDownload;
            UpdateUI();
        }

        /// <summary>
        /// this calls the UpdateRequestsList helper method to obtain 
        /// the current list of transfer requests. 
        /// Then, for each BackgroundTransferRequest object in the list,
        /// a handler for the TransferStatusChanged and TransferProgressChanged events 
        /// are assigned.
        /// </summary>
        private void InitialTransferStatusCheck()
        {
            UpdateRequestsList();

            foreach (var transfer in BackgroundTransferService.Requests)
            {
                transfer.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferStatusChanged);
                transfer.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferProgressChanged);
                ProcessTransfer(transfer);
            }

            if (WaitingForExternalPower)
            {
                MessageBox.Show("You have one or more file transfers waiting for external power. Connect your device to external power to continue transferring.");
            }
            if (WaitingForExternalPowerDueToBatterySaverMode)
            {
                MessageBox.Show("You have one or more file transfers waiting for external power. Connect your device to external power or disable Battery Saver Mode to continue transferring.");
            }
            if (WaitingForNonVoiceBlockingNetwork)
            {
                MessageBox.Show("You have one or more file transfers waiting for a network that supports simultaneous voice and data.");
            }
            if (WaitingForWiFi)
            {
                MessageBox.Show("You have one or more file transfers waiting for a WiFi connection. Connect your device to a WiFi network to continue transferring.");
            }
        }

        private void ProcessTransfer(BackgroundTransferRequest transfer)
        {
            switch (transfer.TransferStatus)
            {
                case TransferStatus.Completed:

                    // If the status code of a completed transfer is 200 or 206, the
                    // transfer was successful
                    if (transfer.StatusCode == 200 || transfer.StatusCode == 206)
                    {
                        string[] param = transfer.Tag.Split('@');

                        // param[0] = chapterId
                        // param[1] = manga name
                        // param[2] = chapter file (Ex: Chapter_001.zip)

                        int chapterId = int.Parse(param[0]);
                        string mangaName = param[1];
                        string chapterFolder = param[2].Substring(0, param[2].LastIndexOf("."));

                        Chapter chapter = App.ViewModel.GetChaptersById(chapterId);

                        // if status of IsDownloaded is equal 2 -> update IsDownloaded to 1 and unzip file
                        if (chapter.IsDownloaded == 2)
                        {
                            App.ViewModel.UpdateIsDownloadedByChapterId(chapter.ChapterId);
                            ISHelper.WorkWithZipFile(transfer.Tag);
                        }

                        // Remove the transfer request in order to make room in the 
                        // queue for more transfers. Transfers are not automatically
                        // removed by the system.
                        RemoveTransferRequest(transfer.RequestId);

                        if ((App.Current as App).isAutoDownload == true)
                        {
                            var ni = NetworkInterface.NetworkInterfaceType;

                            //if (NetworkInterface.GetIsNetworkAvailable() == false)
                            if (ni == NetworkInterfaceType.None)
                            {
                                MessageBox.Show("Bạn không có kết nối internet. Vui lòng thử lại.");
                                return;
                            }

                            Chapter nextChapter = App.ViewModel.GetFirstIsNotDownloadedChapter();
                            if (nextChapter != null)
                            {
                                if (downloadChapter(nextChapter))
                                {
                                    App.ViewModel.UpdateDownloadingById(nextChapter.ChapterId);
                                }
                                else
                                {
                                    MessageBox.Show("Không thể tải nội dung này. Vui lòng thử lại.");
                                    (App.Current as App).isAutoDownload = false;
                                }
                            }
                            else
                            {
                                MessageBox.Show("Đã tải tất cả nội dung.");
                                (App.Current as App).isAutoDownload = false;
                            }

                            this.btnAction.IsEnabled = !(App.Current as App).isAutoDownload;

                        }
                    }
                    else if (transfer.StatusCode == 0)
                    {
                        // StatusCode = 0: request is removed from BackgroundTransferService

                        // Do something if you want
                    }
                    else
                    {
                        // This is where you can handle whatever error is indicated by the
                        // StatusCode and then remove the transfer from the queue. 
                        RemoveTransferRequest(transfer.RequestId);

                        if (transfer.TransferError != null)
                        {
                            // Handle TransferError if one exists.


                        }
                    }
                    break;

                case TransferStatus.WaitingForExternalPower:
                    {
                        //MessageBox.Show("The request is waiting for external power to be connected.");
                        DownloadError(transfer);
                        break;
                    }

                case TransferStatus.WaitingForExternalPowerDueToBatterySaverMode:
                    {
                        //MessageBox.Show("The request is waiting for the device to be connected to external power because the user has enabled Battery Saver mode on this device");
                        DownloadError(transfer);
                        break;
                    }

                case TransferStatus.WaitingForNonVoiceBlockingNetwork:
                    {
                        //MessageBox.Show("This device does not have wifi or network connection.");
                        DownloadError(transfer);
                        break;
                    }

                case TransferStatus.WaitingForWiFi:
                    {
                        //MessageBox.Show("This device does not have wifi or network connection.");
                        DownloadError(transfer);
                        break;
                    }
            }
        }

        // Called when download error
        private void DownloadError(BackgroundTransferRequest transfer)
        {
            try
            {

                string[] param = transfer.Tag.Split('@');

                // param[0] = chapterId
                // param[1] = manga name
                // param[2] = chapter file (Ex: Chapter_001.zip)

                int chapterId = int.Parse(param[0]);
                string mangaName = param[1];
                string chapterFolder = param[2].Substring(0, param[2].LastIndexOf("."));

                // Update 
                App.ViewModel.UpdateNeedToDownloadByChapterId(chapterId);

                // Remove request
                RemoveTransferRequest(transfer.RequestId);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        void transfer_TransferStatusChanged(object sender, BackgroundTransferEventArgs e)
        {
            ProcessTransfer(e.Request);
            UpdateUI();
        }

        void transfer_TransferProgressChanged(object sender, BackgroundTransferEventArgs e)
        {
            UpdateUI();
        }

        private void RemoveTransferRequest(string transferID)
        {
            // Use Find to retrieve the transfer request with the specified ID.
            BackgroundTransferRequest transferToRemove = BackgroundTransferService.Find(transferID);

            // Try to remove the transfer from the background transfer service.
            try
            {
                if (transferToRemove != null)
                {
                    BackgroundTransferService.Remove(transferToRemove);
                }
            }
            catch (Exception e)
            {
                // Handle the exception.
                MessageBox.Show(e.Message);
            }
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            try
            {
                MessageBoxResult msgResult = MessageBox.Show("Bạn có chắc chắn muốn xóa nội dung này?", "Xác nhận", MessageBoxButton.OKCancel);
                if (msgResult == MessageBoxResult.OK)
                {
                    // The ID for each transfer request is bound to the
                    // Tag property of each Remove button.
                    string transferID = ((Button)sender).Tag as string;

                    // Update IsDownloaded 
                    // Get chapterID first
                    string tag = "";
                    foreach (BackgroundTransferRequest request in BackgroundTransferService.Requests)
                    {
                        if (request.RequestId == transferID)
                            tag = request.Tag;
                    }


                    //tag = tag.Substring(0, tag.LastIndexOf("."));
                    string[] param = tag.Split('@');

                    // param[0] = chapterId
                    // param[1] = manga name
                    // param[2] = chapter file (Ex: Chapter_001.zip)

                    int chapterId = int.Parse(param[0]);
                    string mangaName = param[1];
                    string chapterFolder = param[2].Substring(0, param[2].LastIndexOf("."));

                    //Chapter chapter = App.ViewModel.GetChapterByChapterFileName(tag);
                    App.ViewModel.UpdateNeedToDownloadByChapterId(chapterId);
                    // Update



                    // Delete the transfer request
                    RemoveTransferRequest(transferID);

                    // Refresh the list of file transfers
                    UpdateUI();

                    // Change auto download to false
                    (App.Current as App).isAutoDownload = false;
                    btnAction.IsEnabled = true;
                }
            }
            catch (Exception ex)
            {
                // Do something here
            }


        }

        private void homePageButton_Click(object sender, EventArgs e)
        {
            string strUri = String.Format("/MainPage.xaml");
            NavigationService.Navigate(new Uri(strUri, UriKind.Relative));
        }

        private void downloadPageButton_Click(object sender, EventArgs e)
        {
            //string strUri = String.Format("/DownloadPage.xaml");
            //NavigationService.Navigate(new Uri(strUri, UriKind.Relative));
        }

        private void aboutPageButton_Click(object sender, EventArgs e)
        {
            string strUri = String.Format("/AboutPage.xaml");
            NavigationService.Navigate(new Uri(strUri, UriKind.Relative));
        }

        private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
        {
            try
            {
                manga = App.ViewModel.LoadMangaDefault();
                //App.ViewModel.LoadAllMangas();
                //int numManga = App.ViewModel.AllMangas.Count();
                //lstMangaId = new List<int>(numManga);

                //this.MangaListBox.ItemsSource = App.ViewModel.AllMangas;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void chkDownload_Checked(object sender, RoutedEventArgs e)
        {
            try
            {
                CheckBox chkDownload = (CheckBox)sender;

                int mangaId = int.Parse(chkDownload.Tag.ToString());

                lstMangaId.Add(mangaId);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void imgDownloadIcon_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {

        }

        private void chkDownload_Unchecked(object sender, RoutedEventArgs e)
        {
            try
            {
                CheckBox chkDownload = (CheckBox)sender;

                int mangaId = int.Parse(chkDownload.Tag.ToString());

                lstMangaId.Remove(mangaId);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btnAction_Click(object sender, RoutedEventArgs e)
        {
            MessageBoxResult msgResult = MessageBox.Show("Bạn có muốn tự động tải tất cả các nội dung?", "Xác nhận", MessageBoxButton.OKCancel);
            if (msgResult == MessageBoxResult.OK)
            {
                var ni = NetworkInterface.NetworkInterfaceType;

                //if (NetworkInterface.GetIsNetworkAvailable() == false)
                if (ni == NetworkInterfaceType.None)
                {
                    MessageBox.Show("Bạn không có kết nối internet. Vui lòng thử lại.");
                    return;
                }

                if (BackgroundTransferService.Requests.Count() > 0)
                {
                    MessageBox.Show("Vui lòng xóa các nội dung đang tải để thực hiện việc tự động tải.");
                    return;
                }
                else
                {
                    try
                    {
                        (App.Current as App).isAutoDownload = true;
                        Chapter chapter = App.ViewModel.GetFirstIsNotDownloadedChapter();
                        if (chapter != null)
                        {
                            if (downloadChapter(chapter))
                            {
                                App.ViewModel.UpdateDownloadingById(chapter.ChapterId);
                            }
                            else
                            {
                                MessageBox.Show("Không thể tải nội dung này. Vui lòng thử lại.");
                                (App.Current as App).isAutoDownload = false;
                            }
                        }
                        else
                        {
                            MessageBox.Show("Đã tải tất cả nội dung.");
                            (App.Current as App).isAutoDownload = false;
                        }

                        this.btnAction.IsEnabled = !(App.Current as App).isAutoDownload;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }

        private bool downloadChapter(Chapter chapter)
        {
            // Get the URI of the file to be transferred from the Tag property
            // of the button that was clicked.
            string transferFileName = chapter.ChapterFileLink;
            Uri transferUri = new Uri(Uri.EscapeUriString(transferFileName), UriKind.RelativeOrAbsolute);


            // Create the new transfer request, passing in the URI of the file to 
            // be transferred.
            BackgroundTransferRequest transferRequest = new BackgroundTransferRequest(transferUri);

            // Set the transfer method. GET and POST are supported.
            transferRequest.Method = "GET";

            // Get the file name from the end of the transfer URI and create a local URI 
            // in the "transfers" directory in isolated storage.
            string downloadFile = transferFileName.Substring(transferFileName.LastIndexOf("/") + 1);
            // file name
            string fileName = String.Format("{0}@{1}@{2}", chapter.ChapterId, manga.FolderName, downloadFile);
            Uri downloadUri = new Uri("shared/transfers/" + fileName, UriKind.RelativeOrAbsolute);
            transferRequest.DownloadLocation = downloadUri;

            // Pass custom data with the Tag property. In this example, the friendly name
            // is passed.
            transferRequest.Tag = fileName;

            transferRequest.TransferPreferences = TransferPreferences.AllowCellularAndBattery; // v1.2

            // Add the transfer request using the BackgroundTransferService. Do this in 
            // a try block in case an exception is thrown.
            try
            {
                BackgroundTransferService.Add(transferRequest);
                transferRequest.TransferStatusChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferStatusChanged);
                transferRequest.TransferProgressChanged += new EventHandler<BackgroundTransferEventArgs>(transfer_TransferProgressChanged);
                ProcessTransfer(transferRequest);

                return true;
            }
            catch
            {
                // Remove request if something wrong
                foreach (var request in BackgroundTransferService.Requests)
                {
                    if (request.RequestUri == transferRequest.RequestUri)
                    {
                        BackgroundTransferService.Remove(request);
                        break;
                    }
                }
                return false;

            }
        }
    }
}